package com.bringway.global.interceptor;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.web.util.AntPathRequestMatcher;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.bringway.global.dao.UserDao;
import com.bringway.global.domain.SysUserDetails;
import com.bringway.global.service.UserService;
import com.bringway.global.util.GlobalUtils;
import com.bringway.global.util.UserUtil;

/**
 * 拦截器-验证jsp页面权限
 */
@WebFilter(filterName="/JspAuthorityFilter",urlPatterns="*.jsp")
public class JspAuthorityFilter implements Filter {

	Logger logger = Logger.getLogger(JspAuthorityFilter.class);
	
	/**
	 * 不拦截的url列表
	 * */
	private List<String> excludeUrlList;
	
	/**
	 * 需要拦截的url列表
	 * */
	private List<String> inculdeUrlList;
    /**
     * Default constructor. 
     */
    public JspAuthorityFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here

		// pass the request along the filter chain
		HttpServletRequest request = (HttpServletRequest)req;
		HttpServletResponse response = (HttpServletResponse)resp;
		String remoteIp = GlobalUtils.getRemoteAddr(request);
		Map<String, String> reqParams = GlobalUtils.getQuestParamMap(request);
		String referUrl = request.getHeader("Referer");
		String requestUri = request.getRequestURI();
		logger.info("JspAuthorityFilter 请求拦截验证 - remoteIp : " + remoteIp + ", referUrl : " + referUrl + ",请求Uri: "+requestUri+", 请求参数: "+reqParams.toString());
		//判断是否需要验证请求
		boolean isNeedToVerify = this.verifyRequest(request);
		if(isNeedToVerify){
			logger.info("判断当前用户是否拥有页面访问权限！");
			//验证请求权限-判断是否有权限访问菜单
			if(requestUri.contains("page") && requestUri.contains(".jsp")){
				String pageId = MapUtils.getString(reqParams, "pageId","");
				ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(req.getServletContext());
				UserDao userDao = ctx.getBean(UserDao.class);
				SysUserDetails ud = UserUtil.getCurrentUser();
				boolean isHasActhrity = userDao.isHasAuthrity(ud.getId(), ud.getRoleId(), pageId);
				if(!isHasActhrity){//无权限
					logger.error("用户："+ud.getGyh()+",无权限访问："+requestUri);
					response.sendRedirect(request.getContextPath() + "/404.html");
				}else{
					logger.info("权限菜单页面，验证通过，正常访问！");
				}
			}
		}else{
			logger.debug("判断当前用户访问请求无需验证权限！");
		}
		chain.doFilter(req, resp);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		if(null == excludeUrlList){
			excludeUrlList = new ArrayList<>();
			excludeUrlList.add("/index**");
			excludeUrlList.add("/pages/main**");//控制台
			excludeUrlList.add("/pages/main/**");
			excludeUrlList.add("/pages/index/**");
		}
		
		if(null == inculdeUrlList){
			inculdeUrlList = new ArrayList<>();
			inculdeUrlList.add("/pages/p2p/**");
		}
	}
	
	/**
	 * 验证请求是否需要拦截,默认需要验证
	 * true:需要
	 * false:不需要拦截验证
	 * */
	private boolean verifyRequest(HttpServletRequest request){
		if(null!=excludeUrlList && excludeUrlList.size() >0){
			for(int i=0;i<excludeUrlList.size();i++){
				if(new AntPathRequestMatcher(excludeUrlList.get(i)).matches(request)){
					logger.debug("不需要验证");
					return false;
				}
			}
		}else if(null!=inculdeUrlList && inculdeUrlList.size() >0){
			for(int i=0;i<inculdeUrlList.size();i++){
				if(new AntPathRequestMatcher(inculdeUrlList.get(i)).matches(request)){
					logger.debug("需要验证");
					return true;
				}
			}
		}
		return true;
	}

}
